/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ifs.RnD.svnRead;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;

/**
 *
 * @author anaklk
 */
public class Tree {

    private Node rootElement;
    int listIndex;
    String repositoryRoot;

    /**
     * 
     * @param root
     * @param repoRoot
     */
    public Tree(Node root, String repoRoot) {
        super();
        rootElement = root;
        repositoryRoot = repoRoot;
    }

    /**
     * Return the root Node of the tree.
     * @return the root element.
     */
    public Node getRootElement() {
        return this.rootElement;
    }

    /**
     * Set the root Element for the tree.
     * @param rootElement the root element to set.
     */
    public void setRootElement(Node rootElement) {
        this.rootElement = rootElement;
    }

    /**
     * Returns the Tree<T> as a List of Node<T> objects. The elements of the
     * List are generated from a pre-order traversal of the tree.
     * @return a List<Node<T>>.
     */
    public List<Node> toList() {
        List<Node> list = new ArrayList<Node>();
        walk(rootElement, list);
        return list;
    }

    /**
     * Returns a String representation of the Tree. The elements are generated
     * from a pre-order traversal of the Tree.
     * @return the String representation of the Tree.
     */
    @Override
    public String toString() {
        return toList().toString();
    }

    /**
     * Walks the Tree in pre-order style. This is a recursive method, and is
     * called from the toList() method with the root element as the first
     * argument. It appends to the second argument, which is passed by reference * as it recurses down the tree.
     * @param element the starting element.
     * @param list the output of the walk.
     */
    private void walk(Node element, List<Node> list) {
        list.add(element);
        for (Node data : element.getChildren()) {
            walk(data, list);
        }
    }

    /**
     * Check that given String pathPart is available on the List<Node> objects
     * @param pathPart with required path value
     *        List<Node> with Node objects
     * @return return true if the LIst<Node> contain object correspond to pathPart
     */
    private boolean checkChildren(String pathPart, List<Node> list) {
        if (list == null) {
            return false;
        } else {
            for (Node node : list) {
                if (pathPart.equalsIgnoreCase(node.getData())) {
                    listIndex = list.indexOf(node);
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * Insert created Node object as children of parent Node
     * @param pathComp string array of components of the path
     *        type type of the node(file/dir/root)
     *        dirPath actual path of the node
     *        author author of the last revision
     *        revision last revision value
     *        date last modified date
     *        in index as a reference to the data structure containing nodes
     *        root root node of the component
     * @param type 
     * @param in
     * @param dirPath
     * @param root  
     */
    public void insertNode(String[] pathComp, String type, String dirPath, int in, Node root) {

        int index = in;
        Node localRoot = root;
        boolean hasExt = false;

        if (checkChildren(pathComp[index], localRoot.getChildren())) {
            localRoot = localRoot.getChildren().get(listIndex);
            if (index < pathComp.length - 1) {
                index++;
                insertNode(pathComp, type, dirPath, index, localRoot);
            } else {
                return;
            }
            /* before edite                                       
            
            
             */

        } else {
            if (pathComp[index].equalsIgnoreCase("Workspace") || pathComp[index].equalsIgnoreCase("Release") || pathComp[index].equalsIgnoreCase("Documentation")
                    || pathComp[index].equalsIgnoreCase("Test") || pathComp[index].equalsIgnoreCase("Support")) {
                hasExt = true;
            }
            Node newNode = new Node(pathComp[index], type, dirPath, localRoot, hasExt);
            localRoot.addChildToList(newNode);
        }
    }

    /**
     * Insert created Node object as children of parent Node
     * @param pathComp string array of components of the path
     *        type type of the node(file/dir/root)
     *        dirPath actual path of the node
     *        author author of the last revision
     *        revision last revision value
     *        date last modified date
     *        in index as a reference to the data structure containing nodes
     *        root root node of the component
     * @param type 
     * @param extPath 
     * @param in
     * @param root  
     */
    public void insertExtNode(String[] pathComp, String type, String extPath, int in, Node root) {

        int index = in;
        Node localRoot = root;
        boolean hasExt = false;

        if (checkChildren(pathComp[index], localRoot.getChildren())) {
            localRoot = localRoot.getChildren().get(listIndex);
            index++;
            insertNode(pathComp, type, extPath, index, localRoot);
        } else {
            Node newNode = new Node(pathComp[index], type, getUrlStrForParsing(extPath), localRoot, hasExt);
            localRoot.addChildToList(newNode);

        }
    }

    private String getUrlStrForParsing(String elem) {
        try {
            if (elem.startsWith("http:") || elem.startsWith("https:") || elem.startsWith("svn:") || elem.startsWith("file:")) {
                //Assume elem is in correct format.
                return elem;
            } else if (elem.startsWith("^")) {
                elem = elem.substring(1);
                String temp = (SVNURL.parseURIEncoded(repositoryRoot).appendPath(elem, true).toString());
                //System.out.println("element" + elem);
                System.out.println("url" + temp);
                return temp;
            }
        } catch (SVNException ex) {
            ex.printStackTrace();
        }
        return null;
    }
}